home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmcd-1.4 / common.d / util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  9.1 KB  |  568 lines

  1. /*
  2.  *   util.c - Common utility routines for xmcd, cda and libdi.
  3.  *
  4.  *   xmcd  - Motif(tm) CD Audio Player
  5.  *   cda   - Command-line CD Audio Player
  6.  *   libdi - CD Audio Player Device Interface Library
  7.  *
  8.  *
  9.  *   Copyright (C) 1995  Ti Kan
  10.  *   E-mail: ti@amb.org
  11.  *
  12.  *   This program is free software; you can redistribute it and/or modify
  13.  *   it under the terms of the GNU General Public License as published by
  14.  *   the Free Software Foundation; either version 2 of the License, or
  15.  *   (at your option) any later version.
  16.  *
  17.  *   This program is distributed in the hope that it will be useful,
  18.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  *   GNU General Public License for more details.
  21.  *
  22.  *   You should have received a copy of the GNU General Public License
  23.  *   along with this program; if not, write to the Free Software
  24.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  *
  26.  */
  27. #ifndef LINT
  28. static char *_util_c_ident_ = "@(#)util.c    5.3 94/12/28";
  29. #endif
  30.  
  31. #include "common.d/appenv.h"
  32. #include "common.d/util.h"
  33.  
  34. extern char        *progname;
  35. extern appdata_t    app_data;
  36. extern FILE        *errfp;
  37.  
  38. STATIC uid_t        ouid = 30001;    /* Default to something safe */
  39. STATIC gid_t        ogid = 30001;    /* Default to something safe */
  40.  
  41.  
  42. /***********************
  43.  *   public routines   *
  44.  ***********************/
  45.  
  46.  
  47. /*
  48.  * util_init
  49.  *    Initialize the libutil module.  This should be called before
  50.  *    the calling program does a setuid.
  51.  *
  52.  * Args:
  53.  *    Nothing
  54.  *
  55.  * Return:
  56.  *    Nothing
  57.  */
  58. void
  59. util_init(void)
  60. {
  61.     ouid = getuid();
  62.     ogid = getgid();
  63. }
  64.  
  65.  
  66. /*
  67.  * get_ouid
  68.  *    Get original user ID
  69.  *
  70.  * Args:
  71.  *    Nothing
  72.  *
  73.  * Return:
  74.  *    Original uid value.
  75.  */
  76. uid_t
  77. get_ouid(void)
  78. {
  79.     return (ouid);
  80. }
  81.  
  82.  
  83. /*
  84.  * get_ogid
  85.  *    Get original group ID
  86.  *
  87.  * Args:
  88.  *    Nothing
  89.  *
  90.  * Return:
  91.  *    Original gid value.
  92.  */
  93. gid_t
  94. get_ogid(void)
  95. {
  96.     return (ogid);
  97. }
  98.  
  99.  
  100. /*
  101.  * ltobcd
  102.  *    32-bit integer to BCD conversion routine
  103.  *
  104.  * Args:
  105.  *    n - 32-bit integer
  106.  *
  107.  * Return:
  108.  *    BCD representation of n
  109.  */
  110. sword32_t
  111. ltobcd(sword32_t n)
  112. {
  113.     return ((n % 10) | ((n / 10) << 4));
  114. }
  115.  
  116.  
  117. /*
  118.  * bcdtol
  119.  *    BCD to 32-bit integer conversion routine
  120.  *
  121.  * Args:
  122.  *    n - BCD value
  123.  *
  124.  * Return:
  125.  *    integer representation of n
  126.  */
  127. sword32_t
  128. bcdtol(sword32_t n)
  129. {
  130.     return ((n & 0x0f) + ((n >> 4) * 10));
  131. }
  132.  
  133.  
  134. /*
  135.  * stob
  136.  *    String to boolean conversion routine
  137.  *
  138.  * Args:
  139.  *    s - text string "True", "true", "False" or "false"
  140.  *
  141.  * Return:
  142.  *    Boolean value representing the string
  143.  */
  144. bool_t
  145. stob(char *s)
  146. {
  147.     if (strcmp(s, "True") == 0 || strcmp(s, "true") == 0 ||
  148.         strcmp(s, "TRUE") == 0)
  149.         return TRUE;
  150.  
  151.     return FALSE;
  152. }
  153.  
  154.  
  155. /*
  156.  * basename
  157.  *    Return the basename of a file path
  158.  *
  159.  * Args:
  160.  *    path - The file path string
  161.  *
  162.  * Return:
  163.  *    The basename string
  164.  */
  165. char *
  166. basename(char *path)
  167. {
  168.     char    *p;
  169.  
  170.     if ((p = strrchr(path, '/')) == NULL)
  171.         return (path);
  172.     
  173.     return (p + 1);
  174. }
  175.  
  176.  
  177. /*
  178.  * dirname
  179.  *    Return the dirname of a file path
  180.  *
  181.  * Args:
  182.  *    path - The file path string
  183.  *
  184.  * Return:
  185.  *    The dirname string
  186.  */
  187. char *
  188. dirname(char *path)
  189. {
  190.     char        *p;
  191.     static char    buf[FILE_PATH_SZ];
  192.  
  193.     if ((int) strlen(path) >= FILE_PATH_SZ)
  194.         /* Error: path name too long */
  195.         return NULL;
  196.  
  197.     strcpy(buf, path);
  198.  
  199.     if ((p = strrchr(buf, '/')) == NULL)
  200.         return (buf);
  201.     
  202.     *p = '\0';
  203.     return (buf);
  204. }
  205.  
  206.  
  207. /*
  208.  * homedir
  209.  *    Return the home directory path of a user given the uid
  210.  *
  211.  * Args:
  212.  *    uid - The uid of the user
  213.  *
  214.  * Return:
  215.  *    The home directory path name string
  216.  */
  217. char *
  218. homedir(uid_t uid)
  219. {
  220.     struct passwd    *pw;
  221.     char        *cp;
  222.  
  223.     /* Get home directory from the password file if possible */
  224.     if ((pw = getpwuid(uid)) != NULL)
  225.         return (pw->pw_dir);
  226.  
  227.     /* Try the HOME environment variable */
  228.     if (uid == ouid && (cp = getenv("HOME")) != NULL)
  229.         return (cp);
  230.  
  231.     /* If we still can't get the home directory, just set it to the
  232.      * current directory (shrug).
  233.      */
  234.     return (".");
  235. }
  236.  
  237.  
  238. /*
  239.  * uhomedir
  240.  *    Return the home directory path of a user given the name
  241.  *
  242.  * Args:
  243.  *    name - The name of the user
  244.  *
  245.  * Return:
  246.  *    The home directory path name string
  247.  */
  248. char *
  249. uhomedir(char *name)
  250. {
  251.     struct passwd    *pw;
  252.     char        *cp;
  253.  
  254.     /* Get home directory from the password file if possible */
  255.     if ((pw = getpwnam(name)) != NULL)
  256.         return (pw->pw_dir);
  257.  
  258.     /* If we still can't get the home directory, just set it to the
  259.      * current directory (shrug).
  260.      */
  261.     return (".");
  262. }
  263.  
  264.  
  265. /*
  266.  * isqrt
  267.  *    Fast integer-based square root routine
  268.  *
  269.  * Args:
  270.  *    n - The integer value whose square-root is to be taken
  271.  *
  272.  * Return:
  273.  *    Resultant square-root integer value
  274.  */
  275. int
  276. isqrt(int n)
  277. {
  278.     int    a, b, c, as, bs;
  279.  
  280.     a = 1;
  281.     b = 1;
  282.     while (a <= n) {
  283.         a = a << 2;
  284.         b = b << 1;
  285.     }
  286.     as = 0;
  287.     bs = 0;
  288.     while (b > 1 && n > 0) {
  289.         a = a >> 2;
  290.         b = b >> 1;
  291.         c = n - (as | a);
  292.         if (c >= 0) {
  293.             n = c;
  294.             as |= (a << 1);
  295.             bs |= b;
  296.         }
  297.         as >>= 1;
  298.     }
  299.  
  300.     return (bs);
  301. }
  302.  
  303.  
  304. /*
  305.  * blktomsf
  306.  *    CD logical block to MSF conversion routine
  307.  *
  308.  * Args:
  309.  *    blk - The logical block address
  310.  *    ret_min - Minute (return)
  311.  *    ret_sec - Second (return)
  312.  *    ret_frame - Frame (return)
  313.  *    offset - Additional logical block address offset
  314.  *
  315.  * Return:
  316.  *    Nothing.
  317.  */
  318. void
  319. blktomsf(word32_t blk, byte_t *ret_min, byte_t *ret_sec, byte_t *ret_frame,
  320.      word32_t offset)
  321. {
  322.     *ret_min = (blk + offset) / FRAME_PER_SEC / 60;
  323.     *ret_sec = ((blk + offset) / FRAME_PER_SEC) % 60;
  324.     *ret_frame = (blk + offset) % FRAME_PER_SEC;
  325. }
  326.  
  327.  
  328. /*
  329.  * msftoblk
  330.  *    CD MSF to logical block conversion routine
  331.  *
  332.  * Args:
  333.  *    min - Minute
  334.  *    sec - Second
  335.  *    frame - Frame
  336.  *    ret_blk - The logical block address (return)
  337.  *    offset - Additional logical block address offset
  338.  *
  339.  * Return:
  340.  *    Nothing.
  341.  */
  342. void
  343. msftoblk(byte_t min, byte_t sec, byte_t frame, word32_t *ret_blk,
  344.      word32_t offset)
  345. {
  346.     *ret_blk = FRAME_PER_SEC * (min * 60 + sec) + frame - offset;
  347. }
  348.  
  349.  
  350. /*
  351.  * bswap16
  352.  *    16-bit little-endian to big-endian byte-swap routine.
  353.  *    On a big-endian system architecture this routines has no effect.
  354.  *
  355.  * Args:
  356.  *    x - The data to be swapped
  357.  *
  358.  * Return:
  359.  *    The swapped data.
  360.  */
  361. word16_t
  362. bswap16(word16_t x)
  363. {
  364. #if _BYTE_ORDER_ == _L_ENDIAN_
  365.     word16_t    ret;
  366.  
  367.     ret  = (x & 0x00ff) << 8;
  368.     ret |= (word16_t) (x & 0xff00) >> 8;
  369.     return (ret);
  370. #else
  371.     return (x);
  372. #endif
  373. }
  374.  
  375.  
  376. /*
  377.  * bswap24
  378.  *    24-bit little-endian to big-endian byte-swap routine.
  379.  *    On a big-endian system architecture this routines has no effect.
  380.  *
  381.  * Args:
  382.  *    x - The data to be swapped
  383.  *
  384.  * Return:
  385.  *    The swapped data.
  386.  */
  387. word32_t
  388. bswap24(word32_t x)
  389. {
  390. #if _BYTE_ORDER_ == _L_ENDIAN_
  391.     word32_t    ret;
  392.  
  393.     ret  = (x & 0x0000ff) << 16;
  394.     ret |= (x & 0x00ff00);
  395.     ret |= (x & 0xff0000) >> 16;
  396.     return (ret);
  397. #else
  398.     return (x);
  399. #endif
  400. }
  401.  
  402.  
  403. /*
  404.  * bswap32
  405.  *    32-bit little-endian to big-endian byte-swap routine.
  406.  *    On a big-endian system architecture this routines has no effect.
  407.  *
  408.  * Args:
  409.  *    x - The data to be swapped
  410.  *
  411.  * Return:
  412.  *    The swapped data.
  413.  */
  414. word32_t
  415. bswap32(word32_t x)
  416. {
  417. #if _BYTE_ORDER_ == _L_ENDIAN_
  418.     word32_t    ret;
  419.  
  420.     ret  = (x & 0x000000ff) << 24;
  421.     ret |= (x & 0x0000ff00) << 8;
  422.     ret |= (x & 0x00ff0000) >> 8;
  423.     ret |= (x & 0xff000000) >> 24;
  424.     return (ret);
  425. #else
  426.     return (x);
  427. #endif
  428. }
  429.  
  430.  
  431. /*
  432.  * lswap16
  433.  *    16-bit big-endian to little-endian byte-swap routine.
  434.  *    On a little-endian system architecture this routines has no effect.
  435.  *
  436.  * Args:
  437.  *    x - The data to be swapped
  438.  *
  439.  * Return:
  440.  *    The swapped data.
  441.  */
  442. word16_t
  443. lswap16(word16_t x)
  444. {
  445. #if _BYTE_ORDER_ == _L_ENDIAN_
  446.     return (x);
  447. #else
  448.     word16_t    ret;
  449.  
  450.     ret  = (x & 0x00ff) << 8;
  451.     ret |= (word16_t) (x & 0xff00) >> 8;
  452.     return (ret);
  453. #endif
  454. }
  455.  
  456.  
  457. /*
  458.  * lswap24
  459.  *    24-bit big-endian to little-endian byte-swap routine.
  460.  *    On a little-endian system architecture this routines has no effect.
  461.  *
  462.  * Args:
  463.  *    x - The data to be swapped
  464.  *
  465.  * Return:
  466.  *    The swapped data.
  467.  */
  468. word32_t
  469. lswap24(word32_t x)
  470. {
  471. #if _BYTE_ORDER_ == _L_ENDIAN_
  472.     return (x);
  473. #else
  474.     word32_t    ret;
  475.  
  476.     ret  = (x & 0x0000ff) << 16;
  477.     ret |= (x & 0x00ff00);
  478.     ret |= (x & 0xff0000) >> 16;
  479.     return (ret);
  480. #endif
  481. }
  482.  
  483.  
  484. /*
  485.  * lswap32
  486.  *    32-bit big-endian to little-endian byte-swap routine.
  487.  *    On a little-endian system architecture this routines has no effect.
  488.  *
  489.  * Args:
  490.  *    x - The data to be swapped
  491.  *
  492.  * Return:
  493.  *    The swapped data.
  494.  */
  495. word32_t
  496. lswap32(word32_t x)
  497. {
  498. #if _BYTE_ORDER_ == _L_ENDIAN_
  499.     return (x);
  500. #else
  501.     word32_t    ret;
  502.  
  503.     ret  = (x & 0x000000ff) << 24;
  504.     ret |= (x & 0x0000ff00) << 8;
  505.     ret |= (x & 0x00ff0000) >> 8;
  506.     ret |= (x & 0xff000000) >> 24;
  507.     return (ret);
  508. #endif
  509. }
  510.  
  511.  
  512.  
  513. /*
  514.  * dbgdump
  515.  *    Dump a data buffer to screen.
  516.  *
  517.  * Args:
  518.  *    title - Message banner
  519.  *    data - Address of data
  520.  *    len - Number of bytes to dump
  521.  *
  522.  * Return:
  523.  *    Nothing.
  524.  */
  525. void
  526. dbgdump(char *title, byte_t *data, int len)
  527. {
  528.     int    i, j, k, n,
  529.         lines;
  530.  
  531.     if (title == NULL || data == NULL || len <= 0)
  532.         return;
  533.  
  534.     fprintf(errfp, "\n%s:", title);
  535.  
  536.     lines = ((len - 1) / 16) + 1;
  537.  
  538.     for (i = 0, k = 0; i < lines; i++) {
  539.         fprintf(errfp, "\n%04x    ", k);
  540.  
  541.         for (j = 0, n = k; j < 16; j++, k++) {
  542.             if (k < len)
  543.                 fprintf(errfp, "%02x ", *(data + k));
  544.             else
  545.                 fprintf(errfp, "-- ");
  546.  
  547.             if (j == 7)
  548.                 fprintf(errfp, " ");
  549.         }
  550.  
  551.         fprintf(errfp, "   ");
  552.  
  553.         for (j = 0, k = n; j < 16; j++, k++) {
  554.             if (k < len) {
  555.                 fprintf(errfp, "%c",
  556.                     isprint(*(data + k)) ? *(data + k) : '.'
  557.                 );
  558.             }
  559.             else
  560.                 fprintf(errfp, ".");
  561.         }
  562.     }
  563.  
  564.     fprintf(errfp, "\n");
  565. }
  566.  
  567.  
  568.